package com.锁;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;


/**
 *
 * // 造成当前线程在接到信号或被中断之前一直处于等待状态。
 * void await()
 * // 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
 * boolean await(long time, TimeUnit unit)
 * // 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
 * long awaitNanos(long nanosTimeout)
 * // 造成当前线程在接到信号之前一直处于等待状态。
 * void awaitUninterruptibly()
 * // 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
 * boolean awaitUntil(Date deadline)
 * // 唤醒一个等待线程。
 * void signal()
 * // 唤醒所有等待线程。
 * void signalAll()
 *
 *
 *
 *
 */





public class demo02 {


    public static void main(String[] args) {
        P clerk = new P();

      Prod  prod = new Prod(clerk);
        Cusm con = new Cusm(clerk);

        new Thread(prod, "生产者 A").start();
        new Thread(con, "消费者 B").start();

    }

}


class P {
    private  Integer count  = 0 ;

    private ReentrantLock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();



    public void get(){


        lock.lock();

        try {


            if (count >= 1) {


                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

            System.out.println(Thread.currentThread().getName() + ":" + ++count);

            condition.signalAll();

        }finally {
            lock.unlock();
        }


    }


    public void set(){


        lock.lock();

        try {


            if (count <= 0) {



                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

            System.out.println(Thread.currentThread().getName() + ":" + --count);

            condition.signalAll();

        }finally {
            lock.unlock();
        }


    }





}


class Cusm implements Runnable{

    private P p ;

    public Cusm(P p) {
        this.p = p;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            p.get();
        }

    }
}


class Prod implements  Runnable{

    private P p ;

    public Prod(P p) {
        this.p = p;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {


            p.set();
        }

    }
}